// 条件编译：仅在 APP-PLUS 平台（5+ App）下执行
// #ifdef APP-PLUS
const AudioFileManager = {
  // 获取主Activity上下文
  main: plus.android.runtimeMainActivity(),

  // 导入Android原生类
  Environment: plus.android.importClass('android.os.Environment'),
  StatFs: plus.android.importClass('android.os.StatFs'),
  File: plus.android.importClass('java.io.File'),
  FileOutputStream: plus.android.importClass('java.io.FileOutputStream'),
  FileInputStream: plus.android.importClass('java.io.InputStream'),
  BufferedInputStream: plus.android.importClass('java.io.BufferedInputStream'),
  ByteArrayOutputStream: plus.android.importClass(
    'java.io.ByteArrayOutputStream'
  ),

  // 音频文件存储路径
  AudioPath: '',

  /**
   * 初始化音频存储路径
   * 优先使用外部存储，不可用时回退到内部存储
   */
  init: function () {
    if (
      this.Environment.MEDIA_MOUNTED ||
      !this.Environment.isExternalStorageRemovable()
    ) {
      this.AudioPath = this.main.getExternalFilesDir(null).getPath() + '/audios'
    } else {
      this.AudioPath = this.main.getFilesDir().getPath() + '/audios'
    }
    console.log('音频文件存放路径=>', this.AudioPath)

    // 确保目录存在
    this.ensureAudioDirectory()
  },

  /**
   * 确保音频目录存在
   */
  ensureAudioDirectory: function () {
    let file = new this.File(this.AudioPath)
    if (!file.exists()) {
      file.mkdirs()
    }
  },

  /**
   * 保存音频二进制流为MP3文件
   * @param {ArrayBuffer} audioData - 音频二进制数据
   * @param {string} fileName - 文件名（不包含扩展名）
   * @returns {string} 保存的文件路径
   */
  saveAudioAsMP3: function (audioData, fileName = null) {
    if (!fileName) {
      fileName = 'audio_' + getTime('YYYYMMDDhhmmss')
    }

    // 确保文件名以.mp3结尾
    if (!fileName.endsWith('.mp3')) {
      fileName += '.mp3'
    }

    const filePath = this.AudioPath + '/' + fileName

    try {
      // 将ArrayBuffer转换为Java字节数组
      const byteArray = this.arrayBufferToJavaBytes(audioData)
      console.log('audioData', audioData)
      console.log('byteArray', byteArray)

      // 创建文件输出流
      const fos = new this.FileOutputStream(filePath)
      console.log('fos', fos)

      // 写入二进制数据
      fos.write(byteArray)

      // 关闭流
      fos.close()

      console.log('音频文件保存成功=>', filePath)
      return filePath
    } catch (e) {
      console.error('保存音频文件失败=>', e)
      throw e
    }
  },

  /**
   * 将ArrayBuffer转换为Java字节数组
   * @param {ArrayBuffer} arrayBuffer - JavaScript ArrayBuffer
   * @returns {byte[]} Java字节数组
   */
  arrayBufferToJavaBytes: function (arrayBuffer) {
    const uint8Array = new Uint8Array(arrayBuffer)
    const byteArray = plus.android.invoke(
      '[]',
      'newInstance',
      '[B',
      uint8Array.length
    )

    for (let i = 0; i < uint8Array.length; i++) {
      byteArray[i] = uint8Array[i]
    }

    return byteArray
  },

  /**
   * 从Base64字符串保存MP3文件
   * @param {string} base64Data - Base64编码的音频数据
   * @param {string} fileName - 文件名
   * @returns {string} 保存的文件路径
   */
  saveAudioFromBase64: function (base64Data, fileName = null) {
    // 移除Base64前缀（如果有）
    const base64Str = base64Data.replace(/^data:audio\/\w+;base64,/, '')

    // 将Base64转换为ArrayBuffer
    const arrayBuffer = this.base64ToArrayBuffer(base64Str)

    return this.saveAudioAsMP3(arrayBuffer, fileName)
  },

  /**
   * Base64字符串转ArrayBuffer
   * @param {string} base64 - Base64字符串
   * @returns {ArrayBuffer} 二进制数据
   */
  base64ToArrayBuffer: function (base64) {
    const binaryString = atob(base64)
    const bytes = new Uint8Array(binaryString.length)

    for (let i = 0; i < binaryString.length; i++) {
      bytes[i] = binaryString.charCodeAt(i)
    }

    return bytes.buffer
  },

  /**
   * 从文件路径读取音频文件为ArrayBuffer
   * @param {string} filePath - 音频文件路径
   * @returns {ArrayBuffer} 音频二进制数据
   */
  readAudioFile: function (filePath) {
    try {
      const file = new this.File(filePath)
      if (!file.exists()) {
        throw new Error('文件不存在: ' + filePath)
      }

      const fis = new this.FileInputStream(file)
      const bis = new this.BufferedInputStream(fis)
      const baos = new this.ByteArrayOutputStream()

      const buffer = plus.android.invoke('[]', 'newInstance', '[B', 1024)
      let bytesRead = 0

      while ((bytesRead = bis.read(buffer)) !== -1) {
        baos.write(buffer, 0, bytesRead)
      }

      const javaBytes = baos.toByteArray()

      // 关闭所有流
      baos.close()
      bis.close()
      fis.close()

      // 将Java字节数组转换为ArrayBuffer
      return this.javaBytesToArrayBuffer(javaBytes)
    } catch (e) {
      console.error('读取音频文件失败=>', e)
      throw e
    }
  },

  /**
   * 将Java字节数组转换为ArrayBuffer
   * @param {byte[]} javaBytes - Java字节数组
   * @returns {ArrayBuffer} JavaScript ArrayBuffer
   */
  javaBytesToArrayBuffer: function (javaBytes) {
    const arrayBuffer = new ArrayBuffer(javaBytes.length)
    const uint8Array = new Uint8Array(arrayBuffer)

    for (let i = 0; i < javaBytes.length; i++) {
      uint8Array[i] = javaBytes[i] & 0xff // 确保是无符号字节
    }

    return arrayBuffer
  },

  /**
   * 获取音频文件列表
   * @returns {Array} 音频文件信息数组
   */
  getAudioFileList: function () {
    const list = []
    const file = new this.File(this.AudioPath)

    if (!file.exists()) {
      return list
    }

    const tempList = file.listFiles()

    for (let i = 0; i < tempList.length; i++) {
      const audioFile = tempList[i]
      const fileName = audioFile.getName()

      // 只显示音频文件
      if (
        fileName.endsWith('.mp3') ||
        fileName.endsWith('.wav') ||
        fileName.endsWith('.m4a')
      ) {
        list.push({
          index: i,
          name: fileName,
          filePath: audioFile.getPath(),
          size: audioFile.length(),
          updateTime: audioFile.lastModified(),
          formattedSize: transformByteData(audioFile.length()),
          formattedTime: new Date(audioFile.lastModified()).toLocaleString()
        })
      }
    }

    // 按修改时间排序（最新的在前）
    list.sort(function (a, b) {
      return b.updateTime - a.updateTime
    })

    return list
  },

  /**
   * 删除指定的音频文件
   * @param {string} filePath - 要删除的文件路径
   */
  removeAudioFile: function (filePath) {
    try {
      const file = new this.File(filePath)
      if (file.exists()) {
        const success = file.delete()
        if (success) {
          console.log('删除音频文件成功=>', filePath)
        } else {
          console.error('删除音频文件失败=>', filePath)
        }
      }
    } catch (e) {
      console.error('删除音频文件异常=>', e)
    }
  },

  /**
   * 删除所有音频文件
   */
  removeAllAudioFiles: function () {
    const audioFiles = this.getAudioFileList()
    for (let i = 0; i < audioFiles.length; i++) {
      this.removeAudioFile(audioFiles[i].filePath)
    }
    console.log('已删除所有音频文件')
  },

  /**
   * 删除旧的音频文件，保留指定数量的最新文件
   * @param {number} maxFileCount - 最大保留文件数，默认10个
   */
  deleteOldAudioFiles: function (maxFileCount = 10) {
    let audioFiles = this.getAudioFileList()

    if (audioFiles.length > maxFileCount) {
      for (let i = maxFileCount; i < audioFiles.length; i++) {
        this.removeAudioFile(audioFiles[i].filePath)
      }
      console.log(`已删除 ${audioFiles.length - maxFileCount} 个旧音频文件`)
    }
  },

  /**
   * 获取音频文件的总大小
   * @returns {Object} 包含原始大小和格式化后的大小
   */
  getTotalAudioSize: function () {
    const audioFiles = this.getAudioFileList()
    let totalSize = 0

    for (let i = 0; i < audioFiles.length; i++) {
      totalSize += audioFiles[i].size
    }

    return {
      rawSize: totalSize,
      formattedSize: transformByteData(totalSize)
    }
  },

  // 获取设备剩余存储空间的方法（保留原功能）
  getSystemStorage: function () {
    const files = this.Environment.getDataDirectory()
    const statFs = new this.StatFs(files.getPath())
    const blockAva = parseFloat(statFs.getAvailableBlocks())
    const blockSize = parseFloat(statFs.getBlockSize())
    const internalMemSize = blockSize * blockAva

    return {
      rawSize: internalMemSize, // 原始大小
      size: transformByteData(internalMemSize) // 格式化后的值
    }
  }
}

// 初始化音频文件管理器
AudioFileManager.init()
// #endif

// 非APP-PLUS平台的空实现
// #ifndef APP-PLUS
const AudioFileManager = {
  saveAudioAsMP3: function () {
    console.warn('音频保存功能仅在APP平台可用')
    return null
  },
  saveAudioFromBase64: function () {
    console.warn('音频保存功能仅在APP平台可用')
    return null
  },
  getAudioFileList: function () {
    return []
  }
}
// #endif

/**
 * 时间格式化函数（保留原功能）
 */
const getTime = (style = 'YYYY-MM-DD hh:mm:ss') => {
  const time = new Date()
  const pad = num => (num < 10 ? `0${num}` : num)
  const yyyy = time.getFullYear()
  const mm = pad(time.getMonth() + 1)
  const dd = pad(time.getDate())
  const h = pad(time.getHours())
  const m = pad(time.getMinutes())
  const s = pad(time.getSeconds())
  const z = time.getDay()

  const formats = {
    'hh:mm:ss': `${h}:${m}:${s}`,
    'YYYY-MM-DD': `${yyyy}-${mm}-${dd}`,
    YYYYMMDD: `${yyyy}${mm}${dd}`,
    'YYYY-MM-DD hh:mm:ss': `${yyyy}-${mm}-${dd} ${h}:${m}:${s}`,
    YYYYMMDDhhmmss: `${yyyy}${mm}${dd}${h}${m}${s}`,
    YYYY: yyyy,
    MM: mm,
    DD: dd,
    getDay: z
  }

  return formats[style] || formats['YYYY-MM-DD hh:mm:ss']
}

/**
 * 字节数据转换函数（保留原功能）
 */
const transformByteData = (data, digit = 2, extension = '') => {
  if (!data) return `0${extension}B`
  const c = 1024
  const e = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
  const i = Math.floor(Math.log(data) / Math.log(c))
  return (data / c ** i).toFixed(digit) + extension + e[i]
}

export default AudioFileManager
